package com.blog.cloud.auth.oauth.utils;

import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.MediaType;
import com.alibaba.nacos.common.http.param.Query;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;

import java.io.UnsupportedEncodingException;
import java.net.*;
import java.util.*;
import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HttpUtils {
    private static final Pattern CONTEXT_PATH_MATCH = Pattern.compile("(\\/)\\1+");

    public HttpUtils() {
    }

    public static void initRequestHeader(HttpRequestBase requestBase, Header header) {
        Iterator<Map.Entry<String, String>> iterator = header.iterator();

        while(iterator.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry)iterator.next();
            requestBase.setHeader((String)entry.getKey(), (String)entry.getValue());
        }

    }

    public static void initRequestEntity(HttpRequestBase requestBase, Object body, Header header) throws Exception {
        if (body != null) {
            if (requestBase instanceof HttpEntityEnclosingRequest) {
                HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest)requestBase;
                MediaType mediaType = MediaType.valueOf(header.getValue("Content-Type"));
                ContentType contentType = ContentType.create(mediaType.getType(), mediaType.getCharset());
                Object entity;
                if (body instanceof byte[]) {
                    entity = new ByteArrayEntity((byte[])((byte[])body), contentType);
                } else {
                    entity = new StringEntity(body instanceof String ? (String)body : JacksonUtils.toJson(body), contentType);
                }

                request.setEntity((HttpEntity)entity);
            }

        }
    }

    public static void initRequestFromEntity(HttpRequestBase requestBase, Map<String, String> body, String charset) throws Exception {
        if (body != null && !body.isEmpty()) {
            List<NameValuePair> params = new ArrayList(body.size());
            Iterator var4 = body.entrySet().iterator();

            while(var4.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry)var4.next();
                params.add(new BasicNameValuePair((String)entry.getKey(), (String)entry.getValue()));
            }

            if (requestBase instanceof HttpEntityEnclosingRequest) {
                HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest)requestBase;
                HttpEntity entity = new UrlEncodedFormEntity(params, charset);
                request.setEntity(entity);
            }

        }
    }

    public static String buildUrl(boolean isHttps, String serverAddr, String... subPaths) {
        StringBuilder sb = new StringBuilder();
        if (isHttps) {
            sb.append("https://");
        } else {
            sb.append("http://");
        }

        sb.append(serverAddr);
        String pre = null;
        String[] var5 = subPaths;
        int var6 = subPaths.length;

        for(int var7 = 0; var7 < var6; ++var7) {
            String subPath = var5[var7];
            if (!StringUtils.isBlank(subPath)) {
                Matcher matcher = CONTEXT_PATH_MATCH.matcher(subPath);
                if (matcher.find()) {
                    throw new IllegalArgumentException("Illegal url path expression : " + subPath);
                }

                if (pre != null && pre.endsWith("/")) {
                    if (subPath.startsWith("/")) {
                        sb.append(subPath.replaceFirst("\\/", ""));
                    } else {
                        sb.append(subPath);
                    }
                } else if (subPath.startsWith("/")) {
                    sb.append(subPath);
                } else {
                    sb.append('/').append(subPath);
                }

                pre = subPath;
            }
        }

        return sb.toString();
    }

    public static Map<String, String> translateParameterMap(Map<String, String[]> parameterMap) throws Exception {
        Map<String, String> map = new HashMap(16);
        Iterator var2 = parameterMap.entrySet().iterator();

        while(var2.hasNext()) {
            Map.Entry<String, String[]> entry = (Map.Entry)var2.next();
            map.put(entry.getKey(), ((String[])entry.getValue())[0]);
        }

        return map;
    }

    public static String encodingParams(Map<String, String> params, String encoding) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        if (null != params && !params.isEmpty()) {
            Iterator var3 = params.entrySet().iterator();

            while(var3.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry)var3.next();
                if (!StringUtils.isEmpty((String)entry.getValue())) {
                    sb.append((String)entry.getKey()).append('=');
                    sb.append(URLEncoder.encode((String)entry.getValue(), encoding));
                    sb.append('&');
                }
            }

            return sb.toString();
        } else {
            return null;
        }
    }

    public static String encodingParams(List<String> paramValues, String encoding) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        if (null == paramValues) {
            return null;
        } else {
            Iterator<String> iter = paramValues.iterator();

            while(iter.hasNext()) {
                sb.append((String)iter.next()).append('=');
                sb.append(URLEncoder.encode((String)iter.next(), encoding));
                if (iter.hasNext()) {
                    sb.append('&');
                }
            }

            return sb.toString();
        }
    }

    public static String decode(String str, String encode) throws UnsupportedEncodingException {
        return innerDecode((String)null, str, encode);
    }

    public static URI buildUri(String url, Query query) throws URISyntaxException {
        if (query != null && !query.isEmpty()) {
            url = url + "?" + query.toQueryUrl();
        }

        return new URI(url);
    }

    public static boolean isTimeoutException(Throwable throwable) {
        return throwable instanceof SocketTimeoutException || throwable instanceof ConnectTimeoutException || throwable instanceof TimeoutException || throwable.getCause() instanceof TimeoutException;
    }

    private static String innerDecode(String pre, String now, String encode) throws UnsupportedEncodingException {
        if (StringUtils.equals(pre, now)) {
            return pre;
        } else {
            pre = now;
            now = URLDecoder.decode(now, encode);
            return innerDecode(pre, now, encode);
        }
    }
}
